package com.serkol.ams.module.sys.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.serkol.ams.module.sys.entity.SysMenu;
import com.serkol.ams.module.sys.entity.SysUsers;
import com.serkol.ams.module.sys.service.SysUsersService;

import com.serkol.ams.utils.JwtUtils;
import com.serkol.ams.utils.MenuTree;
import com.serkol.ams.utils.R;
import com.serkol.ams.utils.RedisUtil;
import com.serkol.ams.vo.*;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * 用户表
 *
 * @author zlj
 * @email 328727561@qq.com
 * @date 2024-04-17 11:28:08
 */
@RestController
@RequestMapping("sys/authority/users")
public class UsersController {
    @Resource
    private SysUsersService userService;
    @Resource
    private JwtUtils jwtUtils;
    @Resource
    private RedisUtil redisUtil;

    /**
     * 刷新token
     */
    @PostMapping("/refreshToken")
    public R refreshToken(HttpServletRequest request){
        //从header中获取前端提交的token
        String token = request.getHeader("Authorization");
        //如果header中没有参数、则从参数中获取
        if (StrUtil.isEmpty(token)){
            token = request.getParameter("Authorization");
        }
        //获取spring security上下文用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //获取身份信息
        UserDetails userDetails = (UserDetails)authentication.getPrincipal();
        //重新获取token
        String reToken = "";
        //验证原来的token是否合法
        if(jwtUtils.checkToken(token)){
            SysUsers SysUsers = new SysUsers();
            if(!StrUtil.isEmpty(userDetails.getUsername())){
                String username = userDetails.getUsername();

                SysUsers = userService.findUserByUserName(username);
                //生成新的token
                reToken = jwtUtils.getJwtToken(SysUsers.getId().toString(), userDetails.getUsername());
            }
            //获取到token的到期时间
            long expire = redisUtil.getExpire("token_" + token);
            //清除原来的token信息
            redisUtil.del("token_"+token);
            String newTokenKey = "token_"+reToken;
            //将新的token保存到缓存中去
            redisUtil.set(newTokenKey, reToken,18000);
            TokenVo tokenVo = new TokenVo(expire,reToken);
            return R.ok("token刷新成功!").put("data", tokenVo);
        }
        return R.error();
    }
    /**
     * 获取用户信息
     */
    @GetMapping("/getInfo")
    public R getInfo(){
        //从spring Security上下文获取到用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //判断authentication对象是否为空
        if(authentication == null){
            return R.error("用户信息查询失败!");
        }
        //获取用户信息
        SysUsers user = (SysUsers) authentication.getPrincipal();
        //用户权限集合
        List<SysMenu> permissionList = user.getPermissionList();
        //获取角色权限编码字段
        Object[] objects = permissionList.stream().filter(Objects::nonNull).map(SysMenu::getCode).toArray();
        UserInfoVo userInfoVo = new UserInfoVo(user.getId(), user.getNickname(), user.getAvatar(), objects);
        return R.ok("查询用户成功").put("data", userInfoVo);
    }
    /**
     * 退出登录
     */
    @PostMapping("/logout")
    public R logout(HttpServletRequest request, HttpServletResponse response){
        //获取到token
        String authorization = request.getHeader("Authorization");
        //如果头部中没有携带token
        if(ObjectUtil.isEmpty(authorization)){
            //参数中获取token
            authorization = request.getParameter("authorization");
        }
        //从spring security 上下文对象中获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //判断用户信息是否为空,如果不为空、则清空用户信息
        if(authentication != null){


            //清除用户的信息
            new SecurityContextLogoutHandler().logout(request, response, authentication);
            //清除Redis缓存中的token
            redisUtil.del("token_"+authorization);
            return R.ok("正在退出系统!");
        }
        return R.error("退出系统失败!");
    }


        /**
     * APP登录接口
     */
    @PostMapping("/getAppLogin")
    public R getAppLogin(@RequestBody SysUsers user){
        if(ObjectUtil.isEmpty(user)){
            return R.error("用户信息不能为空!");
        }
        R r = userService.getAppLogin(user);
        return r;
    }

    /**
     * 查询所有用户数据
     */
/*
    @PostMapping("/list")
    public R list(@RequestBody UserLoginVo userLoginVo){
        IPage<SysUsers> userList = userService.getUserList(userLoginVo);
        return R.ok().put("data", userList);
    }
*/



    /**
     * 密码(MD5)加密
     */
    @PostMapping("/passwordEncryption")
    public R PasswordEncryption(@RequestBody SysUsers user){
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode(user.getPassword());
        return R.ok("加密后的密文").put("data", encode);
    }

    /**
     * 信息
     */
    @GetMapping("/info/{id}")
    public R info(@PathVariable("id") Long id){
        UserLoginVo userLoginVo = new UserLoginVo();
		SysUsers user = userService.getById(id);
        BeanUtil.copyProperties(user, userLoginVo);
        return R.ok("查询用户成功").put("data", userLoginVo);
    }

    /**
     * 保存
     */
    @PostMapping("/save")
    public R save(@RequestBody SysUsers user){
		userService.save(user);
        return R.ok();
    }

    /**
     * 修改
     */
    @PostMapping("/update")
    public R update(@RequestBody SysUsers user){
        boolean flag = userService.updateById(user);
        if(flag){
            SysUsers byId = userService.getById(user.getId());
            return R.ok("返回修改数据").put("data", byId);
        }
        return R.error("修改数据失败!");
    }

    /**
     * 删除
     */
    @PostMapping("/delete")
    public R delete(@RequestBody Long[] ids){
		userService.removeByIds(Arrays.asList(ids));
        return R.ok();
    }
/*    *//**
     * 找回验证码
     *//*
    @PostMapping("/retrievePassword")
    public R retrievePassword(@RequestBody SysUsers user){
        return userService.retrievePassword(user);
    }

    *//**
     * 修改密码
     *//*
    @PostMapping("/updatePassword")
    public R updatePassword(@RequestBody SysUsers user){
        return userService.updatePassword(user);
    }*/

}
